#Frank算子
'''
coding = 'utf-8'
writingtime:2022-6-30
author: zhaoweijun
reference:
doi:
examiner:
'''
import math
from Utilities.AutoGetOperator.selectPackage import get_func

Operator_IVQ_ROFS=get_func(r'Operators/OperationOperators/OperatorIVQROF.py','Operator_IVQ_ROFS')

class Frank(Operator_IVQ_ROFS):

    #基础和函数
    def add(self, a1, a2, q=0):
        '''
        function:基础和函数
        return:计算结果
        '''
        if q <= 0:
            q = self.q
        t=self.x

        u1_temp=1+((pow(t,(1-a1[0][0]**q))-1)*(pow(t,(1-a2[0][0]**q))-1))/(t-1)
        u2_temp=1+((pow(t,(1-a1[0][1]**q))-1)*(pow(t,(1-a2[0][1]**q))-1))/(t-1)
        u1=pow(1-math.log(u1_temp,t),1/q)
        u2=pow(1-math.log(u2_temp,t),1/q)

        v1_temp=1+((pow(t,(a1[1][0]**q))-1)*(pow(t,(a2[1][0]**q))-1))/(t-1)
        v2_temp=1+((pow(t,(a1[1][1]**q))-1)*(pow(t,(a2[1][1]**q))-1))/(t-1)
        v1=pow(math.log(v1_temp,t),1/q)
        v2=pow(math.log(v2_temp,t),1/q)

        return ([u1, u2], [v1, v2])

    def multi(self, a1, a2, q=0):
        '''
        function:基础积函数
        return:计算结果
        '''
        if q <= 0:
            q = self.q
        t=self.x
        u1_temp = 1 + ((pow(t, (a1[0][0] ** q)) - 1) * (pow(t, (a2[0][0] ** q)) - 1)) / (t - 1)
        u2_temp = 1 + ((pow(t, (a1[0][1] ** q)) - 1) * (pow(t, (a2[0][1] ** q)) - 1)) / (t - 1)
        u1 = pow(math.log(u1_temp, t), 1 / q)
        u2 = pow(math.log(u2_temp, t), 1 / q)

        v1_temp=1+((pow(t,(1-a1[1][0]**q))-1)*(pow(t,(1-a2[1][0]**q))-1))/(t-1)
        v2_temp=1+((pow(t,(1-a1[1][1]**q))-1)*(pow(t,(1-a2[1][1]**q))-1))/(t-1)
        v1=pow(1-math.log(v1_temp,t),1/q)
        v2=pow(1-math.log(v2_temp,t),1/q)

        return ([u1, u2], [v1, v2])

    # 带区间的常数相乘
    def kmulti(self, a, k, q=0):
        '''
        function:基础数乘函数
        return:计算结果
        '''
        if q <= 0:
            q = self.q
        t=self.x

        u1_temp=1+(((pow(t,(1-a[0][0]**q))-1)**k)/pow(t-1,k-1))
        u2_temp=1+(((pow(t,(1-a[0][1]**q))-1)**k)/pow(t-1,k-1))
        u1=pow(1-math.log((u1_temp),t),1/q)
        u2=pow(1-math.log((u2_temp),t),1/q)

        v1_temp=1+(((pow(t,(a[1][0]**q))-1)**k)/pow(t-1,k-1))
        v2_temp=1+(((pow(t,(a[1][1]**q))-1)**k)/pow(t-1,k-1))
        v1=pow(math.log(v1_temp,t),1/q)
        v2=pow(math.log(v2_temp,t),1/q)

        return ([u1, u2], [v1, v2])

    # 带区间的乘方运算
    def pow(self, a, k, q=0):
        '''
        function:基础乘方函数
        return:计算结果
        '''
        if q <= 0:
            q = self.q
        t=self.x

        u1_temp = 1 + (((pow(t, (a[0][0] ** q)) - 1) ** k) / pow(t - 1, k - 1))
        u2_temp = 1 + (((pow(t, (a[0][1] ** q)) - 1) ** k) / pow(t - 1, k - 1))
        u1 = pow(math.log(u1_temp, t), 1 / q)
        u2 = pow(math.log(u2_temp, t), 1 / q)

        v1_temp = 1 + (((pow(t, (1 - a[1][0] ** q)) - 1) ** k) / pow(t - 1, k - 1))
        v2_temp = 1 + (((pow(t, (1 - a[1][1] ** q)) - 1) ** k) / pow(t - 1, k - 1))
        v1 = pow(1 - math.log((v1_temp), t), q / 1)
        v2 = pow(1 - math.log((v2_temp), t), q / 1)

        return ([u1, u2], [v1, v2])

class FrankA(Frank):

    def getResult(self):
        '''
        function：基础的算数平均公式
        :return: AA公式计算的结果
        '''
        result=self.data_list[0]
        for i in range(1,len(self.data_list)):
            result=self.add(result,self.data_list[i])
        result=self.kmulti(result,1/len(self.data_list))

        return result

class FrankGA(Frank):

    def getResult(self):
        '''
        function：基础的算数平均公式
        :return: AA公式计算的结果
        '''
        result = self.data_list[0]
        for i in range(1, len(self.data_list)):
            result = self.multi(result, self.data_list[i])
        result = self.pow(result, 1 / len(self.data_list))

        return result

class FrankWA(Frank):

    def getResult(self):
        '''
        function：基础的加权算数平均公式
        :return: WAA公式计算的结果
        '''
        result = self.kmulti(self.data_list[0],self.weight_list[0])
        for i in range(1, len(self.data_list)):
            temp=self.kmulti(self.data_list[i],self.weight_list[i])
            result = self.add(result, temp)

        return result

class FrankWGA(Frank):

    def getResult(self):
        '''
        function：基础的加权几何平均公式
        :return: WAA公式计算的结果
        '''
        result = self.pow(self.data_list[0],self.weight_list[0])
        for i in range(1, len(self.data_list)):
            temp=self.pow(self.data_list[i],self.weight_list[i])
            result = self.multi(result, temp)

        return result

class OWA(Frank):

    def getResult(self):
        '''
        function：基础的有序加权算数平均公式
        :return: OWAA公式计算的结果
        '''
        # 将 数据集备份，将类中数据集属性 替换为 排序后的数据集
        data_list = self.data_list
        self.data_list = self.sortdata()

        result = self.kmulti(self.data_list[0],self.weight_list[0])
        for i in range(1, len(self.data_list)):
            temp=self.kmulti(self.data_list[i],self.weight_list[i])
            result = self.add(result, temp)

        # 还原数据集
        self.data_list = data_list
        return result

if __name__ == "__main__":
    data= [([0.85, 0.95], [0.1, 0.2]), ([0.8, 0.9], [0.1, 0.2]), ([0.85, 0.95], [0.1, 0.2]), ([0.7, 0.8], [0.2, 0.3]),
        ([0.4, 0.5], [0.5, 0.6])]
    weight_list = [0.1, 0.2, 0.3, 0.1, 0.3]
    result  = FrankWA(data)
